<?php
namespace Admin\Controller;
use Think\Controller;
use Common\Controller\BaseController;
use Common\ORG\Util\UploadFile;
use Admin\Controller\ContactController;

/**
 * 单位信息管理
 * Class LotteryController
 * @package Admin\Controller
 */
class LotteryController extends AdminController {

    //摇号结果状态
    public static $status = array("待入住", "已入住", "已作废");

    /**
     * 系统管理 -> 政务公开 -> 政务分类管理 -> listview
     */
    public function index(){
        //获取搜索条件
        $filter = $this->fn_GenerateFilter();
        $where = $this->fn_GenerateWhereClause();
        $order = $this->fn_GenerateOrderBy();

        //分页信息
        $pageNum = intval(I("post.page"));
        $pageNum = $pageNum==0?1:$pageNum;
        $page = $this->fn_GetPageInfo($where, $pageNum);
        $this->assign("page", $page);

        //搜索出单位信息
        $limit = ($page['from']-1).",".$page['num'];
        $list = M("lottery")->where($where)->order($order)->limit($limit)->select();
        for($i=0; $i<count($list); $i++){
            $list[$i]["offset"] = $page['from']-1+$i;
        }
        $this->assign("list", $list);

        //设置搜索条件
        $this->assign("filter", $filter);
        $batch = $this->fn_GetLotteryDict();
        $this->assign("batch", $batch);
        $this->assign("tmpl", $this->fn_GetMsgTmpl());

        $this->display();
    }

    /**
     * 单位信息维护 -> formview
     */
    public function detail(){
        //读取单位信息
        $dataId = I("get.id");
        $lottery = M("lottery")->where(array("id"=>$dataId))->find();
        $this->assign("lottery", $lottery);

        //查询条件
        $where = $this->fn_GenerateWhereClause();
        $order = $this->fn_GenerateOrderBy();
        $pageInfo = $this->fn_GetPageInfo($where);

        //页面信息
        $offset = intval(I("get.offset"));
        $nearby = $this->fn_FindNearbyItems($where, $order, $offset);
        $page = array_merge($pageInfo, $nearby);
        $this->assign("page", $page);

        // 设置上下文信息
        $context = $this->fn_GenerateContext($page);
        $this->assign("context", $context);

        $options = $this->fn_GetLotteryList();
        $this->assign("options", json_encode ($options));
        $this->assign("state_options", json_encode (self::$status));
        $this->assign("derate_type", ContactController::$derate_type);

        $batch = $this->fn_GetLotteryDict();
        $this->assign("batch", $batch);
        $this->assign("tmpl", $this->fn_GetMsgTmpl());

        $contactDate = array(
            "start" => date('Y/m/d'),
            "end" => date('Y')."/12/31"
        );
        $this->assign('contactDate', $contactDate);

        //渲染加入黑名单对话框
        $this->Render_BlacklistDialog($lottery);
        $this->display();
    }

    public function ajax_changefy(){
        $lotId = I("post.id");
        if (!$lotId) {
            $this->error("缺少必要参数");
        }

        $trans = M();
        $trans->startTrans();   // 开启事务
        try {

            $lottery = M("lottery")->where(array("id"=>$lotId))->find();
            if (!$lottery) {
                $this->error("参数错误，摇号结果没有找到");
            }

            $house = M("house")->where(array("addr"=>I("post.house2")))->find();
            if (!$house) {
                $this->error("参数错误，新房源没有找到");
            }

            //第一步：写入换房日志
            $data = array(
                "house_addr1" => $lottery['house_addr'],
                "house_addr2" => $house['addr'],
                "reason" => I("post.reason"),
                "name" => $lottery['name'],
                "idno" => $lottery['idno'],
                "phone" => $lottery['phone'],
                "cuser" => session("username"),
                "ctime" => date("Y/m/d"),
            );
            $res = M("lottery_log")->add($data);
            if(!$res){
                $this->error("操作失败，换房日志写入失败");
            }

            //第二步：修改合同请信息
            $contact = M("contact")->where(array("no"=>$lottery['contact_no']))->find();
            if(!$contact){
                $this->error("操作失败，合同信息不存在");
            }

            $data = array(
                "zj"=>$house['price'],
                "mzj"=>$house['mprice'],
                "fwdz"=>$house['addr'],
                "fwbh"=>$house['name']
            );
            $res = M("contact")->where(array("no"=>$lottery['contact_no']))->save($data);
            if(!$res){
                $this->error("操作失败，合同信息更新失败");
            }

            //第三步：修改申请信息
            $model = "lzf";
            $data = array("house_addr"=>$house['addr'],"house_no"=>$house['name']);
            $prefix = substr($contact['ywno'], 0, 1);
            if($prefix=="L"){
                $model = "lzf";
            }else if($prefix=="G"){
                $model = "gzf";
            }else{
                $this->error("无效的申请编号");
            }
            $res = M($model)->where(array("no"=>$contact['ywno']))->save($data);
            if(!$res){
                $this->error("操作失败，申请信息更新失败");
            }

            //第四步：修改房源信息，把旧房源数据搞过来
            $oldHouse = M("house")->where(array("addr"=>I("post.house1")))->find();
            if(!$res){
                $this->error("操作失败，旧房源信息不存在");
            }

            $data = array(
                "zhname" => $oldHouse['zhname'],
                "zhidno" => $oldHouse['zhidno'],
                "zhname2" => $oldHouse['zhname2'],
                "zhidno2" => $oldHouse['zhidno2'],
                "jtnum" => $oldHouse['jtnum'],
                "dbnum" => $oldHouse['dbnum'],
                "phone" => $oldHouse['phone'],
                "dibaohm" => $oldHouse['dibaohm'],
                "utime" => time(),
                "state"=>"租赁中"
            );
            $res = M("house")->where(array("addr"=>$house['addr']))->save($data);
            if(!$res){
                $this->error("操作失败，房源信息更新失败");
            }

            //第五步：修改房源信息，把旧房源住户信息清空
            $data = array(
                "zhname" => null, "zhidno" => null,
                "zhname2" => null, "zhidno2" => null,
                "jtnum" => null, "dbnum" => null,"state"=>"闲置中",
                "phone" => null, "dibaohm" => null,"utime"=>time()
            );
            $res = M("house")->where(array("addr"=>$oldHouse['addr']))->save($data);
            if(!$res){
                $this->error("操作失败，旧房源信息更新失败");
            }

            //第六步：修改摇号结果信息
            $data = array(
                "house_addr" => $house['addr'], "utime"=>time()
            );
            $res = M("lottery")->where(array("id"=>$lotId))->save($data);
            if(!$res){
                $this->error("操作失败，摇号信息更新失败");
            }

            $trans->commit();   // 提交事务
            $this->success();
        } catch (Exception $e) {
            $trans->rollback();   // 开启事务
            $this->error($e->getMessage());
        }
    }

    public function ajax_SearchHouseByAddr(){
        $h = array();
        $where = array("state"=>"闲置中", "addr"=>array("like", "%".I("get.house")."%"));
        $house = M("house")->where($where)->select();
        foreach ($house as $v){
            array_push($h, array("value"=>$v["addr"], "data"=>$v));
        }
        $this->ajaxReturn(array('query'=>I("get.house"),'suggestions' => $h));
    }

    private function fn_GetMsgTmpl(){
        $where = array("code"=>"3000");
        return M("sms_tpl")->where($where)->find();
    }

    /**
     * 单位信息维护 -> 新增
     */
    public function add_abort(){
        if(IS_POST){    //添加公司信息
            $data = array(
                "batch_id" => I("post.batch_id"),
                "no" => I("post.no"),
                "seq" => I("post.seq"),
                "name" => I("post.name"),
                "idno" => I("post.idno"),
                "phone" => I("post.phone"),
                "house_addr" => I("post.house_addr"),
                "ctime" => time(),
                "cuser" => session("username"),
            );

            $r1 = M("lzf")->where(array("no"=>$data['no']))->find();
            $r2 = M("gzf")->where(array("no"=>$data['no']))->find();
            if(!$r1 && !$r2){
                $this->error("创建摇号结果失败，业务编号不存在");
            }

            if(!M("house")->where(array("addr"=>$data['house_addr']))->find()){
                $this->error("创建摇号结果失败，房源不存在");
            }

            $dataId = M("lottery")->add($data);
            if($dataId){
                header("Location:/admin/lottery/detail?id=".$dataId);
            }else{
                $this->error("系统错误，创建摇号结果失败");
            }
        }

        //复制信息时处理流程
        if(I("get.id") && I("get.action"=="copy")){
            $lottery = M("lottery")->where(array("id"=>I("get.id")))->find();
            $this->assign("lottery", $lottery);
        }

        $batch = $this->fn_GetLotteryList();
        $this->assign("batch", $batch);
        $this->display();
    }

    public function add(){
        if(IS_POST){    //添加公司信息
            $data = array(
                "batch_id" => I("post.batch_id"),
                "no" => I("post.no"),
                "seq" => I("post.seq"),
                "name" => I("post.name"),
                "name2" => I("post.name2"),
                "idno" => I("post.idno"),
                "idno2" => I("post.idno2"),
                "phone" => I("post.phone"),
                "jtnum" => I("post.jtnum"),
                "dibaohm" => I("post.dibaohm"),
                "dibaork" => I("post.dibaork"),
                "house_addr" => I("post.house_addr"),
                "ctime" => time(),
                "cuser" => session("username"),
            );

            $dataId = $this->action_GenerateInfo($data);
            if($dataId){
                header("Location:/admin/lottery/detail?id=".$dataId);
            }else{
                $this->error("系统错误，创建摇号结果失败");
            }
        }

        //复制信息时处理流程
        if(I("get.id") && I("get.action"=="copy")){
            $lottery = M("lottery")->where(array("id"=>I("get.id")))->find();
            $this->assign("lottery", $lottery);
        }

        $batch = $this->fn_GetLotteryList();
        $this->assign("batch", $batch);
        $this->display();
    }

    public function action_GenerateInfo($data){
        //第一步：验证批次，房源信息
        $batch = M("lottery_batch")->where(array("id"=>$data['batch_id']))->find();
        if(!$batch){
            $this->error("摇号批次不存在");
        }

        $house = M("house h")
            ->field("h.*, c.name as comm")
            ->where(array("h.addr"=>$data['house_addr']))
            ->join(C("DB_PREFIX")."community c on c.id=h.community_id", "LEFT")
            ->find();
        if(!$house){
            $this->error("房源信息：".$data['house_addr']."不存在");
        }

        //第二步：创建申请信息
        if(intval($data['dibaork'])>0){
            //创建廉租房申请信息
            $no = $this->fn_GenerateLzfNo();
            $this->action_LzfImportApply($data, $no);
        }else{
            //创建公租房申请信息
            $no = $this->fn_GenerateGzfNo();
            $this->action_GzfImportApply($data, $no);
        }

        //第三步：创建摇号信息
        $lotInfo = array(
            "no" => $no,
            "seq" => $data['seq'],
            "name" => $data['name'],
            "idno" => $data['idno'],
            "phone" => $data['phone'],
            "house_addr" => $data['house_addr'],
            "batch_id" => $data['batch_id'],
            "state" => '待入住',
        );
        $dataId = M("lottery")->add($lotInfo);
        if(!$dataId){
            $this->error("系统错误，添加摇号结果失败");
        }

        return $dataId;
    }

    private function fn_GetGenderByIdno($idno){
        $tag = substr($idno, 16, 1);
        if($tag%2=='1'){
            return "男";
        }else if($tag%2==0){
            return "女";
        }
        return null;
    }

    private function fn_GetMarriage($name){
        $marriage = '已婚';
        if($name=='丧偶'||$name=='已亡'){
            $marriage = '丧偶';
        }else if($name=='离婚'||$name=='离异'){
            $marriage = '离婚';
        }else if($name=='未婚' || $name==""){
            $marriage = '未婚';
        }
        return $marriage;
    }

    private function action_LzfImportApply($data, $no){
        $marriage = $this->fn_GetMarriage($data["name2"]);
        $apply = array(
            "no" => $no,
            "name" => $data["name"],
            "idno" => $data["idno"],
            "gender" => $this->fn_GetGenderByIdno($data["idno"]),
            "phone" => $data["phone"],
            "resident_num" => intval($data["jtnum"]),
            "dibaohm" => $data["dibaohm"],
            "dibaork" => intval($data["dibaork"]),
            "marriage" => $marriage,
            "area_id" => 1,  //所在社区和党委口
            "stime" => date("Y/m/d"),
            "state" => "pass4",
        );
        $res = M("lzf")->add($apply);
        if(!$res){
            $this->error(M("lzf")->getLastSql());
            $this->error("创建廉租房申请失败");
        }

        if($marriage=='已婚'){
            $family = array(
                "gzf_no" => $apply['no'],
                "name" => $data["name2"],
                "idno" => $data["idno2"],
                "phone" => $data["phone"],
                "gender" => $this->fn_GetGenderByIdno($data["idno2"]),
                "relation" => "配偶",
            );
            $res = M("lzf_family")->add($family);
            if(!$res){
                $this->error("添加家庭成员信息失败");
            }
        }
    }

    private function action_GzfImportApply($data, $no){
        $marriage = $this->fn_GetMarriage($data["name2"]);
        $apply = array(
            "no" => $no,
            "name" => $data["name"],
            "idno" => $data["idno"],
            "gender" => $this->fn_GetGenderByIdno($data["idno"]),
            "phone" => $data["phone"],
            "resident_num" => intval($data["jtnum"]),
            "dibaork" => intval($data["dibaork"]),
            "marriage" => $marriage,
            "area_id" => 1,  //所在社区和党委口
            "stime" => date("Y/m/d"),
            "state" => "pass4",
        );
        $res = M("gzf")->add($apply);
        if(!$res){
            $this->error("创建公租房申请失败");
        }

        if($marriage=='已婚'){
            $family = array(
                "gzf_no" => $apply['no'],
                "name" => $data["name2"],
                "idno" => $data["idno2"],
                "phone" => $data["phone"],
                "gender" => $this->fn_GetGenderByIdno($data["idno2"]),
                "relation" => "配偶",
            );
            $res = M("gzf_family")->add($family);
            if(!$res){
                $this->error("添加家庭成员信息失败");
            }
        }
    }

    private function fn_GenerateGzfNo(){
        $data = array("time"=>date("Y-m-d H:i:s"));
        $no = M("gzf_no")->add($data);
        return "G".$no;
    }

    private function fn_GenerateLzfNo(){
        $data = array("time"=>date("Y-m-d H:i:s"));
        $no = M("lzf_no")->add($data);
        return "L".$no;
    }

    public function ajax_sendMsgBatch()
    {
        $dataIds = I("post.info");
        $code = I("post.code");
        if (!$dataIds || !$code) {
            $this->error("缺少必要参数");
        }

        $lottery = M("lottery")->where(array("id"=>array("in", $dataIds)))->select();
        if(!$lottery){
            $this->error("摇号信息不存在");
        }

        foreach($lottery as $item){
            $params = array("house"=>$item['house_addr']);
            $res = SmsApiController::SendMsg($code, $item['phone'], $params);
            if(!$res['state']){
                \Think\Log::write("短信发送失败：".$res['info']);
            }else{
                \Think\Log::write("短信发送成功：".$res['phone']);
            }
        }
        $this->success("短信发送成功");
    }

    /**
     * AJAX方法，在formview中对发放入住办理短信
     */
    public function ajax_sendMsg()
    {
        $lid = I("post.info");
        $phone = I("post.phone");
        $code = I("post.code");
        if (!$lid || !$phone || !$code) {
            $this->error("缺少必要参数");
        }

        $lottery = M("lottery")->where(array("id"=>$lid))->find();
        if(!$lottery){
            $this->error("摇号信息不存在");
        }

        //发送短信
        $params = array("house"=>$lottery['house_addr']);
        $res = SmsApiController::SendMsg($code, $phone, $params);
        if(!$res['state']){
            \Think\Log::write("短信发送失败：".$res['info']);
            $this->error($res['info']);
        }else{
            \Think\Log::write("短信发送成功：".$res['phone']);
            $this->success("短信发送成功");
        }
    }

    /**
     * AJAX方法，在formview中对申请进行 分配房源
     */
    public function ajax_fenpeify()
    {
        $lotId = I("post.id");
        if (!$lotId) {
            $this->error("缺少必要参数");
        }

        $contactNo = I("post.contact");
        if (!$contactNo) {
            $this->error("缺少必要参数");
        }

        $trans = M();
        $trans->startTrans();   // 开启事务
        try {
            //判断合同是否存在
            $contact = M("contact")->where(array("no" => $contactNo))->find();
            if (!$contact) {
                $this->error("分配失败，合同不存在");
            }

            $house = M("house")->where(array("addr" => $contact['fwdz']))->find();
            if ($house['state']=='租赁中') {
                $this->error("分配失败，房源：".$house['addr']."处于租赁状态中，不能再次分配");
            }

            //添加房源租赁记录
            /*$remarks = "实物配租";
            $res = $this->fn_AddHouseRentalLog($contact, $remarks);
            if (!$res) {
                $this->error("系统错误，房源租赁日志写入失败");
            }*/

            //修改申请状态为done
            $res = $this->fn_MarkApplyDone($contact, I("post.ctime"));
            //$this->error(M()->getLastSql());
            if (!$res) {
                $this->error("系统错误，分配房源失败");
            }

            //修改房源状态为：租赁中
            $res = $this->fn_MarkHouseOccupied($contact, I("post.ctime"));
            if (!$res) {
                $this->error("系统错误，房源状态修改失败");
            }

            //添加租金缴费记录
            $remarks = "签订合同，缴纳租金";
            $zjNo = $this->fn_PayRentalZj($contact, $contact['total'], I("post.ctime"), $remarks);
            if (!$zjNo) {
                $this->error("系统错误，租金缴费记录写入失败");
            }

            //添加押金缴费记录
            $remarks = "签订合同，缴纳押金";
            $yjNo = $this->fn_PayRentalYj($contact, $contact['yj'], I("post.ctime"), $remarks);
            if (!$yjNo) {
                $this->error("系统错误，押金缴费记录写入失败");
            }

            //添加租金减免操作
            if(floatval($contact['derate_money'])>0){
                $res = $this->fn_AddDerateInfo($contact);
                if (!$res) {
                    $this->error("系统错误，添加租金减免记录失败");
                }
            }

            //设置合同状态为：签订
            $res = $this->fn_MarkContactAssigned($contact['id'], $yjNo);
            if (!$res) {
                $this->error("系统错误，合同签订失败");
            }

            //设置摇号为已分配房源状态
            $res = $this->fn_MarkLotteryDone($lotId, $contact);
            if (!$res) {
                $this->error("系统错误，更新摇号状态失败");
            }

            $trans->commit();   // 提交事务
            $this->success("押金交易流水号：".$yjNo."<br />租金交易流水号：".$zjNo);

        } catch (Exception $e) {
            $trans->rollback();   // 开启事务
            $this->error($e->getMessage());
        }
    }

    public function ajax_refuse(){
        $info = I("post.info");
        $reason = I("post.reason");
        if(!$reason){
            $this->error("您还没有填写原因");
        }
        $zxtime = time() + 365*24*3600*intval(I("post.zxyear"));
        $data = array(
            "name" => $info["name"],
            "idno" => $info["idno"],
            "phone" => $info["phone"],
            "reason" => $reason,
            "zxtime" => $zxtime,
            "zxyear" => I("post.zxyear"),
            "remarks" => I("post.remarks"),
            "cuser" => session("username"),
            "ctime" => date("Y/m/d"),
        );

        $isExist = M("blacklist")->where(array("idno"=>$info['idno']))->find();
        if($isExist){
            $this->error("该申请人已经被列入了黑名单");
        }
        $res = M("blacklist")->add($data);
        if(!$res){
            $this->error("系统错误，列入黑名单失败");
        }

        $data = array("state"=>'已作废', "utime"=>time());
        $res = M("lottery")->where(array("id"=>I("post.id")))->save($data);
        if(!$res){
            $this->error("系统错误，更新摇号结果失败");
        }

        $this->success("操作成功");
    }

    private function fn_AddDerateInfo($contact){
        $data = array(
            "name" => $contact['yifang'],
            "idno" => $contact['yfsfz'],
            "phone" => $contact['yfdh'],
            "contact_no" => $contact['no'],
            "community" => $contact['community'],
            "house_no" => $contact['fwbh'],
            "house_addr" => $contact['fwdz'],
            "date1" => $contact['ksrq'],
            "date2" => $contact['jsrq'],
            "yw_no" => $contact['ywno'],
            "type" => $contact['derate_type'],
            "total" => $contact['derate_money'],
            "year" => date("Y"),
            "derate_date" => date("Y/m/d"),
            "cuser" => session("username"),
            "ctime" => time(),
        );
        return M("derate")->add($data);
    }

    private function fn_PayRentalZj($contact, $amount, $payDate, $remarks){
        $dtype = null;
        if($contact['derate_type']=='1至6级军残全额减免'){
            $dtype = '半免';
        }else if($contact['derate_type']=='7级以上军残一半减免'){
            $dtype = '全免';
        }
        $payment = array(
            "name" => $this->fn_GeneratePaymentsNo(),
            "ptype" => $contact['type']."租金",
            "dtype" => $dtype,
            "contact_no" => $contact['no'],
            "community" => $contact['community'],
            "house_no" => $contact['fwbh'],
            "house_addr" => $contact['fwdz'],
            "yw_no" => $contact['ywno'],
            "amount" => $amount,
            "year" => substr($contact['ksrq'], 0, 4),
            "date1" => $contact['ksrq'],
            "date2" => $contact['jsrq'],
            "month_start" => substr($contact['ksrq'], 5, 2),
            "month_end" => substr($contact['jsrq'], 5, 2),
            "type" => "收", //收，付
            "payer" => $contact['yifang'],
            "payer_idno" => $contact['yfsfz'],
            "pdate" => $payDate,
            "remarks" => $remarks,
            "cuser" => session("username"),
            "ctime" => time()
        );
        if(M("payments")->add($payment)){
            return $payment['name'];
        }
        return null;
    }

    private function fn_PayRentalYj($contact, $amount, $payDate, $remarks){
        $payment = array(
            "name" => $this->fn_GeneratePaymentsNo(),
            "ptype" => $contact['type']."押金",
            "contact_no" => $contact['no'],
            "community" => $contact['community'],
            "house_no" => $contact['fwbh'],
            "house_addr" => $contact['fwdz'],
            "yw_no" => $contact['ywno'],
            "amount" => $amount,
            "type" => "收", //收，付
            "payer" => $contact['yifang'],
            "payer_idno" => $contact['yfsfz'],
            "pdate" => $payDate,
            "remarks" => $remarks,
            "cuser" => session("username"),
            "ctime" => time()
        );
        if(M("payments")->add($payment)){
            return $payment['name'];
        }
        return null;
    }

    private function fn_MarkLotteryDone($lotId, $contact){
        $where = array("id"=>$lotId);
        $data = array("contact_no"=>$contact['no'], "state"=>"已入住");
        return M("lottery")->where($where)->save($data);
    }

    protected function fn_MarkContactAssigned($contactId, $payNo){
        $where = array("id"=>$contactId);
        $data = array("pay_no"=>$payNo, "state"=>'已签订', 'qtime'=>date("Y/m/d"));
        return M("contact")->where($where)->save($data);
    }

    private function fn_GetPeiOuInfo($no, $type){
        if($type=='廉租房'){
            $where = array("lzf_no"=>$no, "relation"=>"配偶");
            return M("lzf_family")->field("name,idno,gender,phone")->where($where)->find();
        }else if($type=='公租房'){
            $where = array("gzf_no"=>$no, "relation"=>"配偶");
            return M("gzf_family")->field("name,idno,gender,phone")->where($where)->find();
        }
        return array();
    }

    /**
     * 设置房源状态为：租赁中
     * @param $houseId 房源ID
     * @param $no 申请编号
     * @param $contactId 合同ID
     * @param $rq 分配日期
     */
    protected function fn_MarkHouseOccupied($contact, $rq){
        $model = $this->fn_GetApplyModel($contact['type']);
        $apply = $model->where(array("no"=>$contact['ywno']))->find();
        $houseData = array(
            "rzdate"=> $rq,
            "state" => "租赁中",
            "zhname" => $apply['name'],
            "zhidno" => $apply['idno'],
            "jtnum" => $apply['resident_num'],
            "dbnum" => $apply['dibaork'],
            "dibaohm" => $apply['dibaohm'],
            "phone" => $apply['phone'],
            "yw_no"=> $contact['ywno'],
            "contact_no"=> $contact["no"], "utime"=> time(),
        );
        $peiou = $this->fn_GetPeiOuInfo($contact['ywno'], $contact['type']);
        if($peiou){
            $houseData['zhname2'] = $peiou['name'];
            $houseData['zhidno2'] = $peiou['idno'];
        }
        return M("house")->where(array("name"=>$contact["fwbh"]))->save($houseData);
    }

    private function fn_GeneratePaymentsNo(){
        $data = array("time"=>date("Y-m-d H:i:s"));
        $no = M("payments_no")->add($data);
        return "P".$no;
    }

    /**
     * 将保障房申请的状态设置为：done
     * $no 廉租房编号, $houseId 房源ID $contactId 合同ID $rq 分配日期
     */
    protected function fn_MarkApplyDone($contact, $rq){
        $data = array(
            "contact_no"=> $contact["no"],
            "community"=> $contact["community"],
            "house_no"=> $contact["fwbh"],
            "house_addr"=> $contact["fwdz"],
            "fprq"=> $rq,
            "state"=>"done",
            "utime"=>time()
        );
        $where = array("no"=>$contact["ywno"]);
        $model = $this->fn_GetApplyModel($contact['type']);
        return $model->where($where)->save($data);
    }

    private function fn_GetApplyModel($type){
        if($type=='廉租房'){
            return M("lzf");
        }else if($type=='公租房'){
            return M("gzf");
        }else{
            return M("zlbt");
        }
    }

    /**
     * 添加房源的租赁记录
     * @param $houseId 房源ID
     * @param $name 租赁人姓名
     * @param $idno 租赁人身份证
     */
    protected function fn_AddHouseRentalLog($contact, $remarks){
        $rental = array(
            "type"=>"保障分房",
            "remarks"=> $remarks,
            "cuser"=> self::$u["username"],
            "ctime"=> date("Y/m/d"),
            "house_no"=> $contact["fwbh"],
            "bzdx"=> $contact['yifang'],
            "idno"=> $contact['yfsfz'],
        );
        return M("house_log")->add($rental);
    }

    /**
     * 合同自动补全搜索算法，通过合同编号查找(未签订状态)
     */
    public function ajax_SearchContactByNo(){
        $h = array();
        //默认是查找未签订的合同
        $where = array("state"=>"未签订", "no"=>array("like", "%".I("get.no")."%"));
        $house = M("contact")->where($where)->select();
        foreach ($house as $v){
            array_push($h, array("value"=>$v["no"], "data"=>$v));
        }
        $this->ajaxReturn(array('query'=>I("get.no"),'suggestions' => $h));
    }

    /**
     * AJAX方法，在listview中进行批量删除信息
     */
    public function ajax_del(){

        $dataIds = I("post.info");
        if(count($dataIds)==0){
            $this->error("您还没有选中任何记录");
        }

        $map["id"] = array("in", $dataIds);
        $map['state'] = '待入住';
        $num = M("lottery")->where($map)->count();
        if($num != count($dataIds)){
            $this->error("操作失败，数据无法删除");
        }

        $res = M("lottery")->where($map)->delete();
        if($res){
            $this->success("操作成功");
        }else{
            $this->error("系统错误");
        }
    }

    /**
     * AJAX方法，在formview中进行单条信息删除
     */
    public function ajax_del2(){
        //根据ID删除单位记录
        $id = I("post.id");

        $where = array("id"=>$id, "state"=>'待入住');
        if(!M("lottery")->where($where)->count()){
            $this->error("操作失败，数据无法删除");
        }

        $res = M("lottery")->where(array("id" => $id))->delete();
        if(!$res){
            $this->error("系统错误");
        }

        //分页信息
        $where = $this->fn_GenerateWhereClause();
        $order = $this->fn_GenerateOrderBy();
        $total = $this->fn_GetTotalItems($where);
        if($total==0){
            $this->success(null);
        }

        //计算下一条记录的offset
        $offset = intval(I("post.offset"));
        $offset = ($offset>=$total-1)?0:$offset;

        //获取下一记录的信息
        $nextItem = $this->fn_GetInfoByOffset($offset, $where, $order);
        $this->success($nextItem["id"]); //返回下一条记录的ID
    }

    /**
     * 获取批次信息  array
     * @return mixed
     */
    public function fn_GetLotteryList(){
        return M("lottery_batch")->order("id desc")->select();
    }

    /**
     * 获取批次信息2 key => value
     * @return mixed
     */
    public function fn_GetLotteryDict(){
        $result = array();
        $batch = M("lottery_batch")->order("id desc")->select();
        for($i=0; $i<count($batch); $i++){
            $result[$batch[$i]["id"]] = $batch[$i]["name"];
        }
        return $result;
    }

    /**
     * AJAX方法，通过ID来修改信息
     */
    public function ajax_UpdateInfoById(){
        $data = I("post.data");
        $dataId = I("post.id");
        $res = M("lottery")->where(array("id"=>$dataId))->save($data);
        if($res){
            $this->success("0k, 200");
        }else{
            $this->error("更新异常，请稍候再试");
        }
    }

    /**
     *  辅助方法，通过$_POST的值来生成where查询条件
     */
    private function fn_GenerateWhereClause(){
        $where = array();
        if(I("request.value")){
            if(I("request.field")=="batch_id"){ //多表查询处理
                $dataIds = $this->fn_SelectBatchByName(I("request.value"));
                $where[I("request.field")] = array("in", $dataIds);
            }else{
                $where[I("request.field")] = array("like", "%".I("request.value")."%");
            }
        }
        return $where;
    }

    private function fn_SelectBatchByName($name){
        $where["name"] =  array("like", "%".$name."%");
        $result = M("lottery_batch")->where($where)->field("id")->select();
        $dataIds = array();
        for($i=0; $i<count($result); $i++){
            array_push($dataIds, $result[$i]["id"]);
        }
        return $dataIds;
    }

    /**
     *  辅助方法，通过$_POST的值来生成order by子句
     */
    private function fn_GenerateOrderBy(){
        $order = "id desc";
        if(I("request.order_field") && I("request.order_sort")){
            $order = I("request.order_field") . " " . I("request.order_sort");
        }
        return $order;
    }

    /**
     *  辅助方法，通过$_POST的值来生成Filter (listview)
     */
    private function fn_GenerateFilter(){
        if(IS_POST){
            return array(
                "page" => I("post.page"),
                "field" => I("post.field"),
                "value" => I("post.value"),
                "order_field" => I("post.order_field"),
                "order_sort" => I("post.order_sort"),
            );
        }
        return array(
            "page" => 1,
            "order_field" => "id",
            "order_sort" => "desc",
        );
    }

    /**
     * 辅助方法，通过$_POST的值来生成Context (formvier)
     * @return array
     */
    private function fn_GenerateContext($page){
        return array(
            "id" => I("request.id"),
            "field" => I("request.field"),
            "value" => I("request.value"),
            "order_field" => I("request.order_field"),
            "order_sort" => I("request.order_sort"),
            "page" => I("request.page"),
            "offset" => I("request.offset"),
            "index" => I("get.offset")-($page["curPage"]-1)*$page["num"]+1
        );
    }

    /**
     * 辅助方法，通过where,order,offset来查询信息
     * @param $offset
     * @param $where
     * @param $order
     * @return mixed
     */
    private function fn_GetInfoByOffset($offset, $where, $order){
        $limit = $offset.",1";
        $res =  M("lottery")->field("id,name")->where($where)->order($order)->limit($limit)->select();
        if($res){
            return $res[0];
        }
        return array();
    }

    /**
     * 辅助方法，通过where, curpage, num来生成分页信息
     * @param $where
     * @param int $curPage
     * @param int $num
     * @return array
     */
    private function fn_GetPageInfo($where, $curPage=1, $num=15){
        $total = M("lottery")->where($where)->count();
        $totalPage = ceil($total/$num);
        $nextPage = $curPage==$totalPage?1:($curPage+1);
        $prevPage = $curPage==1?$totalPage:($curPage-1);
        $to = $curPage*$num;
        $res = array(
            "total" => $total,
            "num" => $num,
            "from" => (($curPage-1)*$num+1),
            "to" => $to>$total?$total:$to,
            "curPage" => $curPage,
            "nextPage" => $nextPage,
            "prevPage" => $prevPage
        );
        return $res;
    }

    /**
     * 辅助方法，通过where来统计总的信息数量
     * @param array $where
     * @return mixed
     */
    public function fn_GetTotalItems($where=array()){
        return M("lottery")->where($where)->count();
    }

    /**
     * 辅助方法，通过where, order, offset查询相邻两条数据
     * @param $where
     * @param $offset
     */
    public function fn_FindNearbyItems($where, $order, $offset){
        $total = M("lottery")->where($where)->count();
        $prevOffset = $offset>0?$offset-1:$total-1;
        $nextOffset = $offset>=$total-1?0:$offset+1;
        $prevItem = $this->fn_GetInfoByOffset($prevOffset, $where, $order);
        $nextItem = $this->fn_GetInfoByOffset($nextOffset, $where, $order);
        return array(
            "prev" => array("id"=>$prevItem["id"],"offset"=>$prevOffset),
            "next" => array("id"=>$nextItem["id"],"offset"=>$nextOffset),
        );
    }

    public function import(){
        if(IS_POST){
            $upload = new UploadFile();// 实例化上传类
            $upload->maxSize  = 314572811 ;// 设置附件上传大小
            $upload->allowExts  = array('xls', 'xlsx');// 设置附件上传类型
            $upload->savePath =  './Public/UPLOADS/';// 设置附件上传目录
            $info = $upload->uploadOne($_FILES["excel"]);

            if (!$info['state']){
                $this->error($info["msg"]);
            }

            $trans = M();
            $trans->startTrans();   // 开启事务
            try {
                $newFile = $upload->savePath . $info["info"]['savename'];
                $data = $this->fn_ImportLotteryExcel($newFile);
                for($i=0; $i<count($data); $i++){
                    $data[$i]["cuser"] = session("username");
                    $data[$i]["ctime"] = time();
                    $res = M("lottery")->add($data[$i]);
                    if(!$res){
                        $this->error("第".($i+1)."条数据导入失败");
                    }
                }
                $trans->commit();   // 提交事务
                $this->error("恭喜您，数据导入成功");
            } catch (Exception $e) {
                $trans->rollback();   // 开启事务
                $this->error($e->getMessage());
            }
        }
        $this->display();
    }

    public function fn_ImportLotteryExcel($inputFileName){
        import("Common.ORG.Util.PHPExcel");
        import("Common.ORG.Util.PHPExcel.Writer.Excel5");
        import("Common.ORG.Util.PHPExcel.IOFactory.php");

        try { //  Read your Excel workbook
            $inputFileType = \PHPExcel_IOFactory::identify($inputFileName);
            $objReader = \PHPExcel_IOFactory::createReader($inputFileType);
            $objPHPExcel = $objReader->load($inputFileName);
        } catch(Exception $e) {
            die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
        }

        //  Get worksheet dimensions
        $sheet = $objPHPExcel->getSheet(0);
        $highestRow = $sheet->getHighestRow();
        $highestColumn = $sheet->getHighestColumn();

        $batch = $this->fn_GetBatchNameDict();
        for ($row = 2; $row <= $highestRow; $row++){
            $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);

            if(!M("lottery_batch")->field("id")->where(array("name"=>$rowData[0][0]))->find()){
                $this->error("第".$row."行, 摇号批次名：".$rowData[0][0]."不存在");
            }

            $r1 = M("lzf")->field("id")->where(array("no"=>$rowData[0][2]))->find();
            $r2 = M("gzf")->field("id")->where(array("no"=>$rowData[0][2]))->find();
            if(!$r1 && !$r2){
                $this->error("第".$row."行, 申请编号：".$rowData[0][2]."不存在");
            }

            if(!M("house")->field("id")->where(array("addr"=>$rowData[0][6]))->find()){
                $this->error("第".$row."行, 房源：".$rowData[0][6]."不存在");
            }
        }

        // 第二行开始读取数据
        $fields = array("batch_id", "seq", "no", "name", "idno", "phone", "house_addr");
        $rows = array();
        for ($row = 2; $row <= $highestRow; $row++){
            $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
            $data = array("ctime"=>time(), "cuser"=>session("username"));
            for($i=0; $i<count($rowData[0]); $i++){
                if($fields[$i]=="batch_id"){
                    $data[$fields[$i]] = $batch[$rowData[0][$i]];
                }else{
                    $data[$fields[$i]] = $rowData[0][$i];
                }
            }
            array_push($rows, $data);
        }
        return $rows;
    }

    protected function fn_GetBatchNameDict(){
        $data = array();
        $comm = M("lottery_batch")->field("id,name")->select();
        foreach ($comm as $item) {
            $data[$item['name']] = $item['id'];
        }
        return $data;
    }

    /**
     * 导出摇号中奖名单：
     * 1.如果选中了某些行，则导出所选中的项；
     * 2.如果没有选中任意行，则导出所有的项；
     */
    public function export(){
        $where = array();
        $ids = I("get.ids");
        if($ids){
            $where = "id in (".$ids.")";
        }else if(I("get.field") & I("get.value")){
            $where[I("get.field")] = array("like", "%".I("get.value")."%");
        }
        $this->assign("where", serialize($where));
        $this->display();
    }

    /**
     * 导出公示名单
     * @throws \Exception
     */
    public function ajax_ExportYhjg(){
        $where = unserialize( html_entity_decode(I("post.where")) ); //"被转换成了html实体，需要decode
        $data = M("lottery")->where($where)->order("seq asc")->select();
        $fileName = $this->fn_ExportYhmdExcel($data);
        $this->success($fileName);
    }

    public function fn_ExportYhmdExcel($data){
        import("Common.ORG.Util.PHPExcel");
        import("Common.ORG.Util.PHPExcel.Writer.Excel5");
        import("Common.ORG.Util.PHPExcel.IOFactory.php");

        $inputFileName = "./db/xlsx_tpl/yhjg.xls";
        try { //  Read your Excel workbook
            $inputFileType = \PHPExcel_IOFactory::identify($inputFileName);
            $objReader = \PHPExcel_IOFactory::createReader($inputFileType);
            $objPHPExcel = $objReader->load($inputFileName);
        } catch(Exception $e) {
            die('Error loading file "'.pathinfo($inputFileName,PATHINFO_BASENAME).'": '.$e->getMessage());
        }

        $batch = $this->fn_GetLotteryDict();
        $objPHPExcel->setActiveSheetIndex(0);
        $rowCount = 2; //从第2行开始写数据

        for($i=0; $i<count($data); $i++){
            $objPHPExcel->getActiveSheet()->SetCellValue('A'.$rowCount, $batch[$data[$i]["batch_id"]]);
            $objPHPExcel->getActiveSheet()->SetCellValue('B'.$rowCount, " ".$data[$i]["seq"]);
            $objPHPExcel->getActiveSheet()->SetCellValue('C'.$rowCount, " ".$data[$i]["no"]);
            $objPHPExcel->getActiveSheet()->SetCellValue('D'.$rowCount, " ".$data[$i]["name"]);
            $objPHPExcel->getActiveSheet()->SetCellValue('E'.$rowCount, " ".$data[$i]["idno"]);
            $objPHPExcel->getActiveSheet()->SetCellValue('F'.$rowCount, " ".$data[$i]["phone"]);
            $objPHPExcel->getActiveSheet()->SetCellValue('G'.$rowCount, $data[$i]["house_addr"]);
            $rowCount += 1;
        }

        $objWriter = new \PHPExcel_Writer_Excel2007($objPHPExcel);
        $newFile = '/db/export/'.time().'.xlsx';
        $objWriter->save(".".$newFile);
        return $newFile;
    }
}